/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-11-15     CubeLine       the first version
 */
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#include <string.h>
#include "pms7003.h"
//void
#ifndef      BSP_USING_UART1
#define     BSP_USING_UART1
#endif

#define PMS_UART    "uart1"                     //需要操作的设备
static rt_device_t serial;                      //设备句柄
static struct rt_semaphore rx_sem;              //用于接收消息的信号量
uint8_t RXD_OK_FLAG = 0;                        //接收成功标志位
char PMS_Data_Str[32];                          //接收到的数据
int PMS_Data_Count = 0;                         //数组计数
//struct PMS7003_Data PMS_Sensor;
rt_err_t ret = RT_EOK;

//接收回调函数
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&rx_sem);
    RXD_OK_FLAG = 1;
    return RT_EOK;
}
//串口初始化
int PMS_Serial_init(void)
{

    //查找设备中的串口:
    serial = rt_device_find(PMS_UART);
    if (!serial)
    {
        rt_kprintf("find %s faild!\n", PMS_UART);
        return -RT_ERROR;
    }

    //初始化信号量
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);

    //初始化配置参数
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

    //配置串口参数
    config.baud_rate = BAUD_RATE_9600;  //设置波特率为9600;
//    rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);   //写入配置参数
    if (RT_EOK != rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config))
    {
        rt_kprintf("配置串口设备失败\n");
        return RT_ERROR;
    }
    rt_kprintf("Serial's config is OK!\n");

    //以中断来接收及轮询发送模式打开串口设备
    ret = rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);

    if (ret != RT_EOK)
    {
        rt_kprintf("open device failed\r\n");
        return -RT_ERROR;

    }
    else
    {
        rt_kprintf("open device ok\r\n");
        return RT_EOK;
    }

    //设置接收回调函数
    rt_device_set_rx_indicate(serial, uart_input);

}

//创建PMS7003串口读取线程入口函数
void serial_thread_entry(void *parmeter)
{
    uint8_t str;
    ret = rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
//  设置接收回调函数
    rt_device_set_rx_indicate(serial, uart_input);
    rt_sem_release(&rx_sem);
//  RXD_OK_FLAG = 1;
    while (1)
    {

        while (rt_device_read(serial, -1, &str, sizeof(str)) != 1)
        {
            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
        }
//        rt_kprintf("char is: 0x%x\n", str);
//        rt_kprintf(" %x ", str);
        PMS_Data_Str[PMS_Data_Count++] = str;   //将数据存储到数组中

//      数据满32Byte以后,进行数据校验并存储进结构体中;
        if (PMS_Data_Count >= 32)
        {
            int32_t CheckSum = 0;
            for (int count = 0; count < 30; count++)
            {
                CheckSum += PMS_Data_Str[count];
            }
//            rt_kprintf("CHECK_SUM = %x\n",CheckSum);
//            rt_kprintf("Check_Sum =: %x\n", (PMS_Data_Str[30] << 8) + PMS_Data_Str[31]);

//          满足校验和,存进结构体中;
            if (((PMS_Data_Str[30] << 8) + PMS_Data_Str[31]) == CheckSum)
            {
                PMS_Sensor.FrameHeader[0] = PMS_Data_Str[0];
                PMS_Sensor.FrameHeader[1] = PMS_Data_Str[1];
                PMS_Sensor.FrameLen = PMS_Data_Str[3];
                PMS_Sensor.Std_PM1_0 = (PMS_Data_Str[4] << 8) + PMS_Data_Str[5];
                PMS_Sensor.Std_PM2_5 = (PMS_Data_Str[6] << 8) + PMS_Data_Str[7];
                PMS_Sensor.Std_PM10 = (PMS_Data_Str[8] << 8) + PMS_Data_Str[9];
                PMS_Sensor.Air_PM1_0 = (PMS_Data_Str[10] << 8) + PMS_Data_Str[11];
                PMS_Sensor.Air_PM2_5 = (PMS_Data_Str[12] << 8) + PMS_Data_Str[13];
                PMS_Sensor.Air_PM10 = (PMS_Data_Str[14] << 8) + PMS_Data_Str[15];
                PMS_Sensor.Quan_0_3 = (PMS_Data_Str[16] << 8) + PMS_Data_Str[17];
                PMS_Sensor.Quan_0_5 = (PMS_Data_Str[18] << 8) + PMS_Data_Str[19];
                PMS_Sensor.Quan_1_0 = (PMS_Data_Str[20] << 8) + PMS_Data_Str[21];
                PMS_Sensor.Quan_2_5 = (PMS_Data_Str[22] << 8) + PMS_Data_Str[23];
                PMS_Sensor.Quan_5_0 = (PMS_Data_Str[24] << 8) + PMS_Data_Str[25];
                PMS_Sensor.Quan_10 = (PMS_Data_Str[26] << 8) + PMS_Data_Str[27];
                PMS_Sensor.Version = PMS_Data_Str[28];
                PMS_Sensor.ErrorCode = PMS_Data_Str[29];
                PMS_Sensor.CheckSum = (PMS_Data_Str[30] << 8) + PMS_Data_Str[31];
//                rt_kprintf("PMS_Data_Str_Check_Sum is:%d\n", PMS_Sensor.CheckSum);
            }
            PMS_Data_Count = 0;
//            rt_kprintf("PMS_Data_Str is:%d\n", PMS_Data_Str);
            rt_kprintf("PMS_Sensor.Air_PM2.5 is : %d ug/m3\n",PMS_Sensor.Air_PM2_5);
            rt_kprintf("PMS_Sensor.Quan_2.5 is : %d /0.1L\n",PMS_Sensor.Quan_2_5);
        }

    }
    rt_device_close(serial);
}

void PMS_Read(void)
{
    //创建Serial线程
    rt_thread_t thread = rt_thread_create("Serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
    //创建成功则开始启动线程
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        ret = RT_ERROR;
    }
//    return ret;
}

/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(PMS_Read, uart device sample 2);
